

#include "FbFunction.h"
#include <fb.h>
#include <ti81xxfb.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

#undef  MAX
#define MAX(x, y)               (x > y ? x : y)

static  int     get_regparams(int display_fd, struct ti81xxfb_region_params *regp)
{


    int ret;
    ret = ioctl(display_fd, TIFB_GET_PARAMS, regp);
    if (ret < 0) {
        perror("Can not get region params\n");
        return ret;
    }
    printf("\nReg Params Info:  \n");
    printf("----------------\n");
    printf("region %d postion %d x %d prioirty %d\n",
        regp->ridx,
        regp->pos_x,
        regp->pos_y,
        regp->priority);
    printf("first %d last %d\n",
        regp->firstregion,
        regp->lastregion);
    printf("sc en %d sten en %d\n",
        regp->scalaren,
        regp->stencilingen);
    printf("tran en %d, type %d, key %d\n",
        regp->transen,
        regp->transtype,
        regp->transcolor);
    printf("blend %d alpha %d\n"
        ,regp->blendtype,
        regp->blendalpha);
    printf("bb en %d alpha %d\n",
        regp->bben,
        regp->bbalpha);
    return 0;
}

static  int     get_sccoeff(int display_fd, struct ti81xxfb_scparams *scp)
{
    int ret;
    ret = ioctl(display_fd, TIFB_GET_SCINFO, scp);
    if (ret < 0) {
        perror("Can not get coeff.\n");
        return ret;
    }
    printf("\nCoeff Info:  \n");
    printf("----------------\n");
    printf("input %dx%d to %dx%d coeff %x\n",
        scp->inwidth,
        scp->inheight,
        scp->outwidth,
        scp->outheight,
        (__u32)scp->coeff);
    return 0;
}


static int  enable_Scaling(int display_fd,bool enable)
{
    int         ret;
    struct      ti81xxfb_region_params   regp;

    ret = get_regparams(display_fd,&regp);
    if (ret < 0) {
        perror("Can not get region params\n");
        return ret;
    }

    regp.scalaren= enable ? TI81XXFB_FEATURE_ENABLE:
            TI81XXFB_FEATURE_DISABLE;

    ret = ioctl(display_fd, TIFB_SET_PARAMS, &regp);
    if (ret < 0) {
        printf("failed to set reg params\n");
        return -1;
    }
}

int     setScaling(int display_fd,QSize out)
{
    printf("Display fd:%d\n",display_fd);

    int         ret;
    int         dummy;
    struct      fb_fix_screeninfo            fixinfo;
    struct      fb_var_screeninfo            varinfo, org_varinfo;
    struct      ti81xxfb_scparams            scp;
    ret = ioctl(display_fd, FBIOGET_FSCREENINFO, &fixinfo);
    if (ret < 0) {
        perror("Error reading fixed information.\n");
        return -1;
    }

    ret = ioctl(display_fd, FBIOGET_VSCREENINFO, &varinfo);
    if(ret < 0){
        perror("Can not get var info\n");
        return -1;
    }

    ret = ioctl(display_fd, TIFB_GET_SCINFO, &scp);
    if (ret < 0) {
        perror("Can not get coeff.\n");
    }

    scp.inwidth = varinfo.xres;
    scp.inheight = varinfo.yres;

    scp.outwidth = out.width();
    scp.outheight = out.height();
    scp.coeff = NULL;

    enable_Scaling(display_fd,false);
    ret = ioctl(display_fd, TIFB_SET_SCINFO, &scp);
    if (ret < 0) {
        perror("Can not set coeff.\n");
    }
    enable_Scaling(display_fd,true);



    enable_Scaling(display_fd,false);
    enable_Scaling(display_fd,true);

}

int     getFramebuffer(char *display_dev_name,uchar *&buffer_addr,int width,int height)
{
    int     buffersize, ret , i;
    int     display_fd;
    display_fd = open(display_dev_name, O_RDONLY);
    if (display_fd <= 0) {
        perror("Could not open device\n");
    }

    buffersize = width * height * 4;

    buffer_addr = (unsigned char *) mmap (0, buffersize ,
            (PROT_READ), MAP_SHARED, display_fd, 0);

    if (buffer_addr == MAP_FAILED) {
        printf("%d MMap failed\n",__LINE__);
        ret = -ENOMEM;
    }

    return dup(display_fd);
}


int     InitFrameBuffer(char *display_dev_name,uchar *&buffer_addr,int width,int height)
{
    struct  fb_fix_screeninfo fixinfo;
    struct  fb_var_screeninfo varinfo, org_varinfo;
    int     buffersize, ret , i;
    int     display_fd;

    /* Open the display device */
    display_fd = open(display_dev_name, O_RDWR);
    if (display_fd <= 0) {
        perror("Could not open device\n");
    }

    ret = ioctl(display_fd, FBIOGET_FSCREENINFO, &fixinfo);
    if (ret < 0) {
        perror("Error reading fixed information.\n");
    }

    ret = ioctl(display_fd, FBIOGET_VSCREENINFO, &varinfo);
    if (ret < 0) {
        perror("Error reading variable information.\n");
    }

    memcpy(&org_varinfo, &varinfo, sizeof(varinfo));

    org_varinfo.xres = width;
    org_varinfo.yres = height;

    org_varinfo.xres_virtual = org_varinfo.xres;
    org_varinfo.yres_virtual = org_varinfo.yres * 2;

    org_varinfo.red.length = org_varinfo.green.length
        = org_varinfo.blue.length = org_varinfo.transp.length = 8;

    org_varinfo.red.msb_right = org_varinfo.blue.msb_right =
        org_varinfo.green.msb_right =
        org_varinfo.transp.msb_right = 0;

    org_varinfo.red.offset = 16;
    org_varinfo.green.offset = 8;
    org_varinfo.blue.offset = 0;
    org_varinfo.transp.offset = 24;
    org_varinfo.bits_per_pixel = 32;

    ret = ioctl(display_fd, FBIOPUT_VSCREENINFO, &org_varinfo);

    if (ret < 0) {
        printf("line : %d,Error writing variable information.\n",__LINE__);
    }

    ret = ioctl(display_fd, FBIOGET_FSCREENINFO, &fixinfo);
    if (ret < 0) {
        perror("Error reading fixed information.\n");
    }

    buffersize = fixinfo.line_length * varinfo.yres;

    buffer_addr = (unsigned char *) mmap (0, buffersize * 2,
            (PROT_READ|PROT_WRITE), MAP_SHARED, display_fd, 0);

    if (buffer_addr == MAP_FAILED) {
        printf("MMap failed\n");
        ret = -ENOMEM;
    }

    return dup(display_fd);
}

